<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

// aws php s3 wrapper
require_once APPPATH . 'libraries/s3.class.php';

// simplepie rss/atom feed parser
require_once APPPATH . 'libraries/simplepie/simplepie.inc';

class Bricabox {
	public $VERBOTEN_SUBDOMAINS = array('www', 'admin', 'db', 'app', 'site', 'gapps', 'mail', 'mailman', 'postman');
	
	public function Bricabox()
	{
		$this->find_all_app_domains();
		$this->find_app_domain();
		$this->find_bricabox();
	}
	
	public function find_bricabox()
	{
		global $BBX, $VERBOTEN_SUBDOMAINS;
		
		$CI =& get_instance();
		$CI->load->database();
		
		$BBX['white_label'] = array('matrix', 'startupmap', 'mashbase', 'whostech');
		
		// try to find a bricabox in the following order:
		// 1. by a custom domain name
		// 2. by a subdomain
		$BBX['in_bbx'] = false;
		$subless 	   = $BBX['request']['subless_host'];
		
		// memcache
		$save_mc = true;
		$has_mc  = false;
		$mc_key  = preg_replace('/[^a-z0-9]/i', '', "bricabox_{$subless}");
		if ($BBX['memcache'] !== false)
		{
			$has_mc = true;
			
			log_message('debug', 'memcache: looking for '.$mc_key);
			$mc_bricabox = $BBX['memcache']->get($mc_key);
			if ($mc_bricabox === false)
			{
				log_message('debug', 'memcache: '.$mc_key.' not found');
				$save_mc = true;
			}
			else
			{
				log_message('debug', 'memcache: found '.$mc_key);
				$save_mc = false;
			}
		}
		else
		{
			// no memcached
		}
		
		if (!in_array($subless, $BBX['app_domains']))
		{
			// try to find a bricabox using a custom domain which matches the current host
			// passing path and host accounts for weirdness MT was giving for certain domain names with subdomains present
			
			if ($save_mc)
			{
				$params = array(
					@$BBX['request']['parts']['path'],
					@preg_replace('/^www\./', '', $BBX['request']['parts']['path']), // strip www.
					@$BBX['request']['parts']['host'],
					@preg_replace('/^www\./', '', $BBX['request']['parts']['host']) // strip www.
				);
				$query = $CI->db->query('select * from bricaboxes where use_custom_domain = 1 and (custom_domain = ? or custom_domain = ? or custom_domain = ? or custom_domain = ?) limit 1', $params);
				if ($query->num_rows() == 1)
				{
					$BBX['bricabox']	  = $query->first_row();
					$BBX['in_bbx']		  = true;
					$BBX['custom_domain'] = true;
					
					// save to memcached
					if ($has_mc)
					{
						log_message('debug', "memcache: saving {$mc_key}");
						$BBX['memcache']->set($mc_key, $BBX['bricabox'], MEMCACHE_COMPRESSED, 30); // 30s TTL
					}
				}
			}
			else
			{
				// get cached obj
				$_unser_bricabox 	  = $mc_bricabox;
				$BBX['bricabox']	  = $_unser_bricabox;
				$BBX['in_bbx']		  = true;
				$BBX['custom_domain'] = true;
			}
		}
		else
		{
			// find the bricabox by the current subdomain, if one exists and isn't verboten
			if ($BBX['subdomain'] !== false && !in_array($BBX['subdomain'], $this->VERBOTEN_SUBDOMAINS))
			{
				if ($save_mc)
				{
					$query = $CI->db->query('select * from bricaboxes where subdomain = ? limit 1', array($BBX['subdomain']));
					if ($query->num_rows() == 1)
					{
						$BBX['bricabox'] = $query->first_row();
						$BBX['in_bbx']	 = true;
						
						// save to memcached
						if ($has_mc)
						{
							log_message('debug', "memcache: saving {$mc_key}");
							$BBX['memcache']->set($mc_key, $BBX['bricabox'], MEMCACHE_COMPRESSED, 30); // 30s TTL
						}
					}
				}
				else
				{
					// get cached obj
					$_unser_bricabox = $mc_bricabox;
					$BBX['bricabox'] = $_unser_bricabox;
					$BBX['in_bbx'] 	 = true;
				}
			}
		}
	}
	
	// determines which app_domain record we're running the site off of
	public function find_app_domain()
	{
		global $BBX;
		
		$CI =& get_instance();
		$CI->load->database();
		
		$app_domain = $CI->db->query('select * from app_domains where domain = ?', array($BBX['request']['subless_host']));
		if ($app_domain->num_rows())
		{
			$app			   = $app_domain->first_row();
			$BBX['app_domain'] = $app;
			return $app;
		}
	}
	
	// returns an array of all domains from the app_domains table (also saves to $BBX)
	public function find_all_app_domains()
	{
		global $BBX;
		
		$CI =& get_instance();
		$CI->load->database();
		
		$has_mc = ($BBX['memcache'] === false) ? false : true;
		$mc_key = "app_domains";
		if ($has_mc)
			$mc_ad = $BBX['memcache']->get($mc_key);
		else
			$mc_ad = false;
		
		if ($mc_ad === false)
		{
			$query = $CI->db->query('select domain from app_domains');

			$domains = array();
			if ($query->num_rows())
			{
				foreach ($query->result() as $row)
				{
					$domains[] = $row->domain;
				}
			}
			
			if ($has_mc)
			{
				log_message('debug', "memcache: caching app_domains");
				$BBX['memcache']->set($mc_key, $domains, MEMCACHE_COMPRESSED, 3600); // 1 hr TTL
			}
		}
		else
		{
			log_message('debug', "memcache: using cached app_domains");
			$domains = $mc_ad;
		}
		
		$BBX['app_domains'] = $domains;
		return $domains;
	}
	
	public function show_step($step_name)
	{
		global $BBX;
		
		$CI =& get_instance();
		$CI->load->database();
		
		switch ($step_name)
		{
			case 'homepage':
			case 'content':
			{
				$query = $CI->db->query('select count(*) as count_all from block_instances where bricabox_id = ? and location = ?', array($BBX['bricabox']->id, $step_name));
				if ($query->first_row()->count_all == 0)
					return true;
			}
			break;
			
			case 'template':
			{
				$query = $CI->db->query('select count(*) as count_all from content_types where bricabox_id = ?', array($BBX['bricabox']->id));
				if ($query->first_row()->count_all == 0)
					return true;
			}
			break;
			
			case 'entry':
			{
				$query = $CI->db->query('select count(*) as count_all from contents where bricabox_id = ?', array($BBX['bricabox']->id));
				if ($query->first_row()->count_all == 0)
					return true;
			}
			break;
			
			case 'member':
			{
				$query = $CI->db->query('select count(*) as count_all from memberships where bricabox_id = ?', array($BBX['bricabox']->id));
				if ($query->first_row()->count_all == 0)
					return true;
			}
			break;
			
			case 'desc':
			{
				if (strlen($BBX['bricabox']->description) == "")
					return true;
			}
			break;
		}
	}
	
	public function show_panel()
	{
		$show  = false;
		$steps = array('homepage', 'content', 'template', 'entry', 'member', 'desc');
		foreach ($steps as $step)
			if ($this->show_step($step) === true)
				$show = true;
		
		return $show;
	}
	
	public function label_for_entry_tab($singular = false)
	{
		global $BBX;
		
		$CI =& get_instance();
		$CI->load->database();
		
		if (!isset($BBX['bricabox']))
			return false;
		
		$bricabox_id = $BBX['bricabox']->id;
		$query		 = $CI->db->query('select count(*) as count_all from content_types where bricabox_id = ?', array($bricabox_id));
		if ($query->first_row()->count_all == 1)
		{
			$query = $CI->db->query('select name from content_types where bricabox_id = ?', array($bricabox_id));
			return $singular ? $query->first_row()->name : Inflect::pluralize($query->first_row()->name);
		}
		else
			return $singular ? 'Entry' : 'Entries';
	}
	
	/**
	 * Returns true if the given bricabox has the given block in its layout
	 */
	public function bricabox_has_block($bricabox_id, $block_name)
	{
		$CI =& get_instance();
		$CI->load->database();
		
		$query = $CI->db->query('select * from block_instances
		where bricabox_id = ? and block_id =
			(select id from blocks where name = ? limit 1)', array($bricabox_id, $block_name));
		if ($query->num_rows())
			return true;
	}
}

// there is probably a better place for this, but since this lib is always loaded, this is okay for now.
// code from: http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/

// Thanks to http://www.eval.ca/articles/php-pluralize (MIT license)
//           http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/inflections.rb (MIT license)
//           http://www.fortunecity.com/bally/durrus/153/gramch13.html
//           http://www2.gsu.edu/~wwwesl/egw/crump.htm
//
// Changes (12/17/07)
//   Major changes
//   --
//   Fixed irregular noun algorithm to use regular expressions just like the original Ruby source.
//       (this allows for things like fireman -> firemen
//   Fixed the order of the singular array, which was backwards.
//
//   Minor changes
//   --
//   Removed incorrect pluralization rule for /([^aeiouy]|qu)ies$/ => $1y
//   Expanded on the list of exceptions for *o -> *oes, and removed rule for buffalo -> buffaloes
//   Removed dangerous singularization rule for /([^f])ves$/ => $1fe
//   Added more specific rules for singularizing lives, wives, knives, sheaves, loaves, and leaves and thieves
//   Added exception to /(us)es$/ => $1 rule for houses => house and blouses => blouse
//   Added excpetions for feet, geese and teeth
//   Added rule for deer -> deer

// Changes:
//   Removed rule for virus -> viri
//   Added rule for potato -> potatoes
//   Added rule for *us -> *uses

class Inflect
{
    static $plural = array(
        '/(quiz)$/i'               => "\$1zes",
        '/^(ox)$/i'                => "\$1en",
        '/([m|l])ouse$/i'          => "\$1ice",
        '/(matr|vert|ind)ix|ex$/i' => "\$1ices",
        '/(x|ch|ss|sh)$/i'         => "\$1es",
        '/([^aeiouy]|qu)y$/i'      => "\$1ies",
        '/(hive)$/i'               => "\$1s",
        '/(?:([^f])fe|([lr])f)$/i' => "\$1\$2ves",
        '/(shea|lea|loa|thie)f$/i' => "\$1ves",
        '/sis$/i'                  => "ses",
        '/([ti])um$/i'             => "\$1a",
        '/(tomat|potat|ech|her|vet)o$/i'=> "\$1oes",
        '/(bu)s$/i'                => "\$1ses",
        '/(alias)$/i'              => "\$1es",
        '/(octop)us$/i'            => "\$1i",
        '/(ax|test)is$/i'          => "\$1es",
        '/(us)$/i'                 => "\$1es",
        '/s$/i'                    => "s",
        '/$/'                      => "s"
    );

    static $singular = array(
        '/(quiz)zes$/i'             => "\$1",
        '/(matr)ices$/i'            => "\$1ix",
        '/(vert|ind)ices$/i'        => "\$1ex",
        '/^(ox)en$/i'               => "\$1",
        '/(alias)es$/i'             => "\$1",
        '/(octop|vir)i$/i'          => "\$1us",
        '/(cris|ax|test)es$/i'      => "\$1is",
        '/(shoe)s$/i'               => "\$1",
        '/(o)es$/i'                 => "\$1",
        '/(bus)es$/i'               => "\$1",
        '/([m|l])ice$/i'            => "\$1ouse",
        '/(x|ch|ss|sh)es$/i'        => "\$1",
        '/(m)ovies$/i'              => "\$1ovie",
        '/(s)eries$/i'              => "\$1eries",
        '/([^aeiouy]|qu)ies$/i'     => "\$1y",
        '/([lr])ves$/i'             => "\$1f",
        '/(tive)s$/i'               => "\$1",
        '/(hive)s$/i'               => "\$1",
        '/(li|wi|kni)ves$/i'        => "\$1fe",
        '/(shea|loa|lea|thie)ves$/i'=> "\$1f",
        '/(^analy)ses$/i'           => "\$1sis",
        '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i'  => "\$1\$2sis",
        '/([ti])a$/i'               => "\$1um",
        '/(n)ews$/i'                => "\$1ews",
        '/(h|bl)ouses$/i'           => "\$1ouse",
        '/(corpse)s$/i'             => "\$1",
        '/(us)es$/i'                => "\$1",
        '/s$/i'                     => ""
    );

    static $irregular = array(
        'move'   => 'moves',
        'foot'   => 'feet',
        'goose'  => 'geese',
        'sex'    => 'sexes',
        'child'  => 'children',
        'man'    => 'men',
        'tooth'  => 'teeth',
        'person' => 'people'
    );

    static $uncountable = array(
        'sheep',
        'fish',
        'deer',
        'series',
        'species',
        'money',
        'rice',
        'information',
        'equipment'
    );

    public static function pluralize( $string )
    {
        // save some time in the case that singular and plural are the same
        if ( in_array( strtolower( $string ), self::$uncountable ) )
            return $string;

        // check for irregular singular forms
        foreach ( self::$irregular as $pattern => $result )
        {
            $pattern = '/' . $pattern . '$/i';

            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string);
        }

        // check for matches using regular expressions
        foreach ( self::$plural as $pattern => $result )
        {
            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string );
        }

        return $string;
    }

    public static function singularize( $string )
    {
        // save some time in the case that singular and plural are the same
        if ( in_array( strtolower( $string ), self::$uncountable ) )
            return $string;

        // check for irregular plural forms
        foreach ( self::$irregular as $result => $pattern )
        {
            $pattern = '/' . $pattern . '$/i';

            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string);
        }

        // check for matches using regular expressions
        foreach ( self::$singular as $pattern => $result )
        {
            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string );
        }

        return $string;
    }

    public static function pluralize_if($count, $string)
    {
        if ($count == 1)
            return "1 $string";
        else
            return $count . " " . self::pluralize($string);
    }
}

function mysql_now()
{
	return date('Y-m-d H:i:s', time());
}

function mc_key($table, $id, $version)
{
	return "{$table}_{$id}_{$version}";
}

function debug($var){
	
	echo "<h3 style='color:red'>Debugger:</h3>";
	echo "<pre>";
	print_r($var);
	echo "</pre>";
}

?>